package tp1

import scala.collection.mutable.HashMap


trait Calculable {

  def getCursadas():List[Cursada]
  
  def cursadasAprobadas(): Int = {
    var lista = this.getCursadas.filter(this.esAprobada(_))
    lista.foldLeft(0)((acum, elem) => { acum + 1 })
  } 
//    julia.corteAnual(2012).cursadasAprobadas()
//  julia.cursadasAprobadas()

  def cursadasAprobadas(cursadas: List[Cursada]): Int = {
    var lista = cursadas.filter(this.esAprobada(_))
    lista.foldLeft(0)((acum, elem) => { acum + 1 })
  }

  def cursosAbandonados(): Int = {
    var lista = this.cursadasQueAbandono(this.getCursadas)
    lista.foldLeft(0)((acum, elem) => { acum + 1 })
  }
  
  def cursosAbandonados(cursadas: List[Cursada]): Int = {
    var lista = this.cursadasQueAbandono(cursadas)
    lista.foldLeft(0)((acum, elem) => { acum + 1 })
  }

  def cursosAprobadoSobreIniciados(): Double = {
    (this.cursadasAprobadas(this.getCursadas) * 100) / this.getCursadas.length
  }
  
  def cursosAprobadoSobreIniciados(cursadas: List[Cursada]): Double = {
    (this.cursadasAprobadas(cursadas) * 100) / cursadas.length
  }
  
    def promedioConAplazos():Double = {
	  var lista = this.cursadasTerminadas(this.getCursadas)
	  var sumaDeNotas = lista.foldLeft(0)((acum, elem) => {acum + elem.calificacion})
	  sumaDeNotas / lista.length
	}

  def promedioConAplazos(cursadas: List[Cursada]):Double = {
	  var lista = this.cursadasTerminadas(cursadas)
	  var sumaDeNotas = lista.foldLeft(0.0)((acum, elem) => {acum + elem.calificacion})
	  sumaDeNotas / lista.length
	}
  
  def promedioSinAplazos():Double = {
	  var lista = this.getCursadas.filter(this.esAprobada(_))
	  var sumaDeNotas = lista.foldLeft(0.0)((acum, elem) => {acum + elem.calificacion})  
	  sumaDeNotas / lista.length
	}
  
  def promedioSinAplazos(cursadas: List[Cursada]):Double = {
	  var lista = cursadas.filter(this.esAprobada(_))
	  var sumaDeNotas = lista.foldLeft(0)((acum, elem) => {acum + elem.calificacion})  
	  sumaDeNotas / lista.length
	}

  def tablaDeNotas():HashMap[Int,Int] = {
	  var tabla = new HashMap[Int,Int]
	  1.to(10).foreach(agregarIndice(_,tabla,this.getCursadas))
	  tabla
	}
  
  def tablaDeNotas(cursadas: List[Cursada]):HashMap[Int,Int] = {
	  var tabla = new HashMap[Int,Int]
	  1.to(10).foreach(agregarIndice(_,tabla,cursadas))
	  tabla
	}
  
    def notaMasAltaAlmenosXVeces(cantidad:Int):Int = {
	  val tabla = this.tablaDeNotas(this.getCursadas)
	  var notasContadas = tabla(10)
	  var notaActual=9
	  while(notasContadas < cantidad && notaActual > 0){
	    notasContadas += tabla(notaActual)
	    notaActual -=1
	  }
	  if(notasContadas >= cantidad){
	    notaActual
	  }
	  notaActual
	  }

  
  def notaMasAltaAlmenosXVeces(cantidad:Int,cursadas: List[Cursada]):Int = {
	  val tabla = this.tablaDeNotas(cursadas)
	  var notasContadas = tabla(10)
	  var notaActual=9
	  while(notasContadas < cantidad && notaActual > 0){
	    notasContadas += tabla(notaActual)
	    notaActual -=1
	  }
	  if(notasContadas >= cantidad){
	    notaActual
	  }
	  notaActual
	  }
  
  //Auxiliares
  def esAprobada(cursada: Cursada): Boolean = cursada match {
    case ap: Aprobada => true
    case _ => false
  }

  def esAbandonada(cursada: Cursada): Boolean = cursada match {
    case a: Abandonada => true
    case _ => false
  }

  def fueTerminada(cursada: Cursada): Boolean = cursada match {
    case a: Aprobada => true
    case d: Desaprobada => true
    case _ => false
  }

  def cursadasQueAbandono(cursadas: List[Cursada]): List[Cursada] = {
    cursadas.filter(this.esAbandonada(_))
  }
  
  def cursadasTerminadas(cursadas: List[Cursada]):List[Cursada] = {
	  cursadas.filter(this.fueTerminada(_))
	} 
  
  def agregarIndice(indice:Int, tabla:HashMap[Int,Int],cursadas: List[Cursada]){
	  tabla.put(indice, cantidadDe(indice,cursadas))
	}
	
	def cantidadDe(numero:Int, cursadas: List[Cursada]):Int={
	  val listaDelNumero= cursadas.filter(_.calificacion == numero)
	  listaDelNumero.foldLeft(0){(acum, elem) => acum + 1}
	}
}